#! /bin/sh -
#
# The installer of Dragora GNU/Linux-Libre
#
# Copyright (c) 2019-2020 Matias Fonzo, <selk@dragora.org>.
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program.  If not, see <http://www.gnu.org/licenses/>.

# Exit immediately on any error
set -e

PROGRAM="${0##*/}"
TMPDIR="${TMPDIR:-$HOME}"
TMPFILE="${TMPDIR}/${PROGRAM}.${RANDOM-0}$$"
LOCKFILE=/tmp/dragora-installer.lockfile

# Override locale settings
LC_ALL=C
LANGUAGE=C
export LC_ALL LANGUAGE

unmountFilesystems()
{
    for filesystem in /media/dragora-root/sys   \
                      /media/dragora-root/proc  \
                      /media/dragora-root/dev   \
                      /media/dragora-root ;     \
    do
        if mountpoint -q "$filesystem"
        then
            echo "Unmounting ${filesystem} ..."
            if ! umount -v "$filesystem"
            then
                echo "Doing a lazy unmount for $filesystem ..."
                umount -v -l "$filesystem"
            fi
        fi
    done
    unset filesystem
}

chkstatus_or_exit()
{
    status=$?

    # Clean up temporary files
    rm -f -- "$TMPFILE" "$LOCKFILE"

    # Clean up temporary subdirectory if 'PRESERVE' is unset or null
    test -z "$PRESERVE" && rm -rf -- "$SUBTMPDIR"

    # Unmount possible (previously) mounted file systems
    unmountFilesystems

    if test $status -ne 0
    then
        printf "%s\n" "" "^ Return status = $status" 1>&2
        exit 2;
    fi

    unset status
}

# Sanity checks

if test ! -d "$TMPDIR"
then
    echo "${PROGRAM}: \`${TMPDIR}' is not a qualified temporary directory" 1>&2
    exit 1;
fi
if test ! -w "$TMPDIR"
then
    echo "${PROGRAM}: \`${TMPDIR}' is not a writable temporary directory" 1>&2
    exit 1;
fi

trap 'chkstatus_or_exit' EXIT HUP INT QUIT ABRT TERM

umask 077;	# Remove access for all but user.

# Set a lock to allow only one instance of the installer

if ( set -C ; echo ": $PROGRAM - locked" > $LOCKFILE ) 2> /dev/null
then
    true
else
    if test -e "$LOCKFILE"
    then
        echo "Only one instance of \`${PROGRAM}' is allowed." 1>&2
        exit 1;
    else
        echo "${PROGRAM}: \`${LOCKFILE}' lock failed." 1>&2
        exit 2;
    fi
fi

# Create subdirectory to store the files produced by the installer

SUBTMPDIR="${TMPDIR}/.${PROGRAM}"	# Default sets to "${HOME}/.dragora-installer".
mkdir -p -m 700 -- $SUBTMPDIR

umask 022;	# Remove write permission for group and other.

# Detect and prepare initial list of Linux partition(s)

if fdisk -l | sed -e 's|Linux filesystem|Linux|g' | egrep -q -m 1 'Linux$'
then
    fdisk -l | sed -e 's|Linux filesystem|Linux|g' | egrep 'Linux$' | \
     LC_COLLATE=C sort > ${SUBTMPDIR}/partitions
else
    printf "%s\n" \
     "    Linux partitions were not detected."                               \
     ""                                                                      \
     "A Linux partition is required to continue the installation.  You can"  \
     "use utilities such as fdisk(8), cfdisk(8) or parted(8) to create at"   \
     "least one Linux partition.  Then run \`${PROGRAM}' again."
     exit 1;
fi

# Determine the maximum size of the terminal to be used on the dialogues.
# Try using shell variables that set LINES and COLUMNS, first.
echo "Checking terminal size ..."
if test -z "$LINES"
then
    LINES="$(tput lines)" || \
     { LINES="$(stty size)" && LINES="${LINES% *}"; }
fi
if test -z "$COLUMNS"
then
    COLUMNS="$(tput cols)" || \
     { COLUMNS="$(stty size)" && COLUMNS="${COLUMNS#* }"; }
fi
echo "$LINES $COLUMNS"

export SUBTMPDIR LINES COLUMNS

dialog --colors \
 --backtitle "\ZbThe installer of Dragora GNU/Linux-Libre 3.0" \
 --title "INSTALLER INFORMATION" \
 --cr-wrap --msgbox \
"Welcome to \Z3${PROGRAM}\Zn.\n\n\
This program will help you install Dragora 3.0 on your computer.

Use the cursor keys to move around in the installer's menus.

Press \Z3[Tab]\Zn to jump to the next option and \
\Z3[Shift]\Zn\Zb\Z7+\Zn\Z3[Tab]\Zn to jump to the previous one.

Use \Z3[Space]\Zn to select or unselect an item, \Z3[Enter]\Zn to confirm \
or proceed to the next menu.

You can use \Z3[Ctrl]\Zn\Zb\Z7+\Zn\Z3[C]\Zn to abort the installation at \
any time.

To quit a dialog (such as the one you are in), press \Z3[Esc]\Zn.

" 23 $((COLUMNS - 8))

# Try to detect and mount the hybrid ISO image, there may be a USB memory
# stick already inserted.  If not, the media menu will be displayed.

mkdir -p -- /media/dragora-medium

if ! blkid -t LABEL="Dragora Packages" > /dev/null
then
    dialog --colors \
     --backtitle "\ZbInstallation Medium" \
     --title "Pendrive/SDCard/CDROM" \
     --msgbox \
"Please insert the medium labeled \"Dragora Packages\" and\n\
press \Z3[Enter]\Zn to continue.  Otherwise, a media selection menu\n\
will be displayed." 7 65
    if blkid -t LABEL="Dragora Packages" > /dev/null
    then
        if ! mountpoint -q /media/dragora-medium
        then
            mount -v -t iso9660 LABEL="Dragora Packages" /media/dragora-medium && \
             echo "/media/dragora-medium/packages" > ${SUBTMPDIR}/MediumFound
            sleep 2
        fi
    else
        . @PARTS@MenuMedia
    fi
else
    if ! mountpoint -q /media/dragora-medium
    then
        mount -v -t iso9660 LABEL="Dragora Packages" /media/dragora-medium
        sleep 2
    fi
    echo "/media/dragora-medium/packages" > ${SUBTMPDIR}/MediumFound
fi

# Attempt to unmount possible pre-mounted filesystem(s)
mountpoint -q /media/dragora-root/sys && umount /media/dragora-root/sys
mountpoint -q /media/dragora-root/proc && umount /media/dragora-root/proc
mountpoint -q /media/dragora-root/dev && umount /media/dragora-root/dev

# Clean up possible empty mount-directories
rmdir -- \
 /media/dragora-medium \
 /media/dragora-root 2> /dev/null || true

# Double-check to see the installation directory
if test ! -f "${SUBTMPDIR}/MediumFound"
then
    dialog --colors \
     --backtitle "\ZbInstallation Medium" \
     --title "MEDIUM NOT FOUND" \
     --sleep 7 --infobox \
"\nNo means of installation was found to proceed with\n\
the installation of Dragora.  Please check your\n\
drives and the directory containing the software\n\
packages." 8 55
    exit 99;
fi

. @PARTS@MakeSwap;		# Verify/give format to a Swap partition.
. @PARTS@MakeFS;		# Verify/give format to Linux partitions.
. @PARTS@FstabEdit;		# File system table edition (fstab).
. @PARTS@MountRoot;		# Mount root partition for installation.
. @PARTS@FstabMounts;		# Mount rest of file systems from fstab.
. @PARTS@ShowSeries;		# Show software series.
. @PARTS@InstallPackages;	# Package installation.
. @PARTS@PostInstall;		# Post installation.
. @PARTS@SetPassword;		# Set password for root.
. @PARTS@MenuBootloader;	# Boot loader installation.
. @PARTS@ConfServices;		# Running services.


if test -e /media/dragora-root/etc/fstab
then
    if mountpoint -q /media/dragora-medium
    then
        umount /media/dragora-medium
    fi
    if test -s ${SUBTMPDIR}/SeTCDdev
    then
        _status=0
        dialog --clear --colors \
         --title "The Setup for Dragora has been completed" \
         --msgbox \
"\nWhen you are ready, you can press \Z3[Enter]\Zn to eject\nthe installation (CDROM) disc...\n" 8 55 || _status=$?
        if test $_status -eq 0
        then
            cdrom_device="$(cat -- ${SUBTMPDIR}/CDDevice)"

            # Try to eject using SCSI commands, fallback on CDROM eject command
            eject --scsi $cdrom_device || eject --cdrom $cdrom_device

            dialog \
             --title "The Setup for Dragora has been completed" \
             --msgbox "\nPlease remove the installation disc.\n" 7 44 || true

            # Attempt to use the tray close command
            eject -t $cdrom_device > /dev/null 2>&1 || true
        fi
        unset _status cdrom_device
    fi
fi

sync

_status=0
dialog --clear --colors \
 --backtitle "\ZbSystem restart" \
 --title "The Setup for Dragora has been completed" \
 --yesno \
"\nWould you like to reboot the system now?.\n" 7 46 || _status=$?
case $_status in
0)
    unset _status
    dialog --clear
    unmountFilesystems
    exec reboot -d -f
    ;;
*)
    unset _status
    unmountFilesystems
    echo ""
    echo ""
    echo ""
    echo "Going out to the shell..."
    echo ""
    echo ""
    exit 0
    ;;
esac

